package com.java1234.controller;

import com.alibaba.excel.EasyExcel;
import com.java1234.entity.Emp;
import com.java1234.entity.PageBean;
import com.java1234.entity.R; // 使用 R 类
import com.java1234.service.EmpService;
import com.java1234.util.ExcelUtils;
import com.java1234.util.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 资料库管理Controller
 * @author 邓清文
 */
@Slf4j
@RestController
@RequestMapping("/bsns/resource/resmags")
public class EmpController {

    @Autowired
    private EmpService empService;

    @Autowired
    private LogUtil logUtil;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate1;

    /**
     * 分页查询资料信息
     *
     * @param page     当前页码，默认为1
     * @param pageSize 每页显示的记录数，默认为5
     * @param name     资料名
     * @param restype  资源类型
     * @param cont     下载次数
     * @param begin    上传日期
     * @param end      结束日期
     */

    @GetMapping
    public R page(@RequestParam(defaultValue = "1") Integer page,
                  @RequestParam(defaultValue = "5") Integer pageSize,
                  String name, Short restype, Integer cont,
                  @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
                  @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
        log.info("查询员工列表, 参数: {},{},{},{},{},{},{}", page, pageSize, name, restype, cont, begin, end);
        // 调用 service 查询员工列表
        PageBean pageBean = empService.page(page, pageSize, name, restype, cont, begin, end);
        redisTemplate1.opsForHash().put("pageEmps", String.valueOf(pageBean.getTotal()), pageBean);
        return R.ok().put("data", pageBean);
    }

    /**
     * 根据ID批量删除资料信息
     * @param ids 需要删除的资料ID列表
     */
    @DeleteMapping("/{ids}")
    public R delete(@PathVariable List<Integer> ids, HttpServletRequest request) {
        log.info("批量删除操作, ids:{}", ids);
        empService.delete(ids);
        for (Integer id : ids) {
            String cacheKey = "emp:id:" + id;
            redisTemplate1.delete(cacheKey);
        }
        logUtil.logOperation(request, "批量删除资料信息", "DELETE", ids.toString(), "成功");
        return R.ok();
    }

    /**
     * 新增资料信息
     * @param emp 新增的资料对象
     */
    @PostMapping("/save")
    public R save(@RequestBody Emp emp, HttpServletRequest request) {
        log.info("新增, emp: {}", emp);

        empService.save(emp);

        logUtil.logOperation(request, "新增资料信息", "POST", emp.toString(), "成功");
        return R.ok();
    }

    /**
     * 根据ID查询资料信息
     * @param id 需要查询的资料ID
     */
    @GetMapping("/{id}")
    public R getById(@PathVariable Integer id) {
        log.info("根据ID查询信息, id: {}", id);

        // 构建缓存键
        String cacheKey = "emp:id:" + id;

        // 尝试从缓存中获取数据
        Emp emp = (Emp) redisTemplate1.opsForValue().get(cacheKey);
        if (emp == null) {
            // 缓存中没有数据，调用 service 查询
            emp = empService.getById(id);
            if (emp == null) {
                return R.error("资料未找到");
            }
            // 将数据存入缓存 缓存1小时
            redisTemplate1.opsForValue().set(cacheKey, emp, 3600);
        }

        return R.ok().put("data", emp);
    }

    /**
     * 更新资料信息
     * @param emp 需要更新的资料对象
     */
    @PutMapping("/update")
    public R update(@RequestBody Emp emp, HttpServletRequest request) {
        log.info("更新信息 : {}", emp);
        if (emp.getName() == null && emp.getRestype() == null && emp.getImage() == null && emp.getCont() == null) {
            return R.error("至少需要更新一个字段");
        }
        empService.update(emp);

        logUtil.logOperation(request, "更新资料信息", "PUT", emp.toString(), "成功");
        return R.ok();
    }

    /**
     * 更新资料的下载次数
     * @param emp 需要更新下载次数的资料对象
     */
    @PutMapping("/cont")
    public R contUpdate(@RequestBody Emp emp) {
        log.info("更新下载次数 : {}", emp);
        empService.contUpdate(emp);

        return R.ok();
    }

    @GetMapping("/exportExcel")
    public void exportExcel(HttpServletResponse response)  {

        List<Emp> list = empService.getList();

        ExcelUtils.exportExcel(response, list, Emp.class, "资料信息","资料信息");
    }

    @GetMapping("/template")
    public void template(HttpServletResponse response)  {
        ExcelUtils.downloadTemplate(response, Emp.class, "资料信息模板", "资料信息");
    }

    /**
     * 导入
     *
     * @param file 上传的文件
     * @return 导入结果
     */
    @PostMapping("/importExcel")
    public R importExcel(@RequestPart(value = "file") MultipartFile file) {
        try {
// 读取excel数据
            List<Emp> empList = EasyExcel.read(file.getInputStream())
                    .head(Emp.class)
                    .sheet()
                    .doReadSync();
// 记录导入成功和失败记录数
            int successNum = 0;
            int errorNum = 0;
// 保存数据
            for (Emp emp : empList) {
// 设置密码

                Boolean result = empService.save(emp);
                if (result) {
                    successNum++;
                } else {
                    errorNum++;
                }
            }
            if (empList.size() == successNum) {
                return R.ok("全部导入成功，共计" + successNum + "条！");
            } else if (empList.size() == errorNum) {
                return R.ok("全部导入失败，共计" + errorNum + "条！");
            } else {
                return R.ok("部分导入成功：" + successNum + "条，失败：" + errorNum
                        + "条！");
            }
        } catch (IOException e) {
            return R.error("导入失败！");
        }
    }


    /**
     * 根据ID下载文件
     * @param id 需要下载的资料ID
     */
    @GetMapping("/download/{id}")
    public ResponseEntity<Resource> downloadFile(@PathVariable Integer id) {
        log.info("下载文件, id: {}", id);

        // 根据ID获取文件信息
        Emp emp = empService.getById(id);
        if (emp == null) {
            log.warn("文件未找到, id: {}", id);
            return ResponseEntity.notFound().build();
        }

        // 获取文件URL和文件名
        String fileUrl = emp.getImage();
        String fileName = emp.getName();

        try {
            URI uri = new URI(fileUrl);
            Resource resource = new UrlResource(uri);

            if (!resource.exists() || !resource.isReadable()) {
                log.error("文件不存在或不可读: {}", fileUrl);
                return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
            }

            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName + ".pdf", StandardCharsets.UTF_8));
            headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_PDF_VALUE);

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.APPLICATION_PDF)
                    .body(resource);
        } catch (URISyntaxException e) {
            log.error("URI语法错误: {}", e.getMessage());
        } catch (Exception e) {
            log.error("文件读取错误: {}", e.getMessage());
        }

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
    }

}
